package com.hamll.order.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hamll.common.client.ItemClient;
import com.hamll.common.client.UserClient;
import com.hamll.common.dto.AddressDTO;
import com.hamll.common.dto.ItemDTO;
import com.hamll.order.mapper.OrderMapper;
import com.hamll.order.pojo.Order;
import com.hamll.order.pojo.OrderDetail;
import com.hamll.order.pojo.OrderLogistics;
import com.hamll.order.pojo.RequestParams;
import com.hamll.order.service.IOrderService;
import com.hamll.order.utils.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.nio.charset.StandardCharsets;
import java.util.Date;

@Slf4j
@Service
public class OrderService extends ServiceImpl<OrderMapper, Order> implements IOrderService {


    @Autowired
    private ItemClient itemClient;
    @Autowired
    private UserClient userClient;
    @Autowired
    private OrderDetailService detailService;
    @Autowired
    private OrderLogisticsService logisticsService;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long createOrder(RequestParams requestParams) {
        Order order = new Order();
        // 1.查询商品
        ItemDTO item = itemClient.getById(requestParams.getItemId());
        // 2.基于商品价格、购买数量计算商品总价：totalFee
        long totalFee = item.getPrice() * requestParams.getNum();
        order.setTotalFee(totalFee);
        order.setPaymentType(requestParams.getPaymentType());
        order.setUserId(UserHolder.getUserId());
        order.setStatus(1);
        order.setCreateTime(new Date());
        // 3.将Order写入数据库tb_order表中
        this.save(order);

        // 4.将商品信息、orderId信息封装为OrderDetail对象，写入tb_order_detail表
        OrderDetail detail = new OrderDetail();
        detail.setName(item.getName());
        detail.setSpec(item.getSpec());
        detail.setPrice(item.getPrice());
        detail.setNum(requestParams.getNum());
        detail.setItemId(item.getId());
        detail.setImage(item.getImage());
        detail.setOrderId(order.getId());
        detailService.save(detail);

//        保存订单物流信息
        Long addressId = requestParams.getAddressId();
        // 5.根据addressId查询user-service服务，获取地址信息
        AddressDTO address = userClient.findAddressById(addressId);
        // 6.将地址封装为OrderLogistics对象，写入tb_order_logistics表
        OrderLogistics orderLogistics = new OrderLogistics();
//        属性拷贝
        BeanUtils.copyProperties(address, orderLogistics);
        orderLogistics.setOrderId(order.getId());
        logisticsService.save(orderLogistics);

        // 7.扣减库存
        try {
            itemClient.updateStock(requestParams.getItemId(), requestParams.getNum());
        } catch (Exception e) {
            throw new RuntimeException("库存不足！");
        }


        // 创建消息
        Message message = MessageBuilder
                .withBody(order.getId().toString().getBytes(StandardCharsets.UTF_8))
                .setExpiration("30000") //延迟60秒
                .build();
        // 消息ID，需要封装到CorrelationData中
        CorrelationData correlationData = new CorrelationData(order.getId().toString());
        // 发送消息
        rabbitTemplate.convertAndSend("order.topic", "order.create", message, correlationData);
        log.info("发送消息成功");
        return order.getId();
    }
}
